#include <mutex>
#include <condition_variable>
#include <queue>

using namespace std::chrono;

class QueueEmpty : public std::exception {
};

template<class T>
class ThreadQueue {
private:
    std::mutex mutex;
    std::condition_variable signal;
    std::queue<T> queue;

public:
    void push(T &&data) {
        std::lock_guard<std::mutex> lock{mutex};
        queue.push(std::move(data));
        signal.notify_one();
    }

    auto tryGetOne(bool front = false) {
        std::unique_lock<std::mutex> lock{mutex};
        if (queue.empty()) signal.wait_for(lock, 300ms);
        if (queue.empty())throw QueueEmpty();
        for (int i = 0; front && i < queue.size() - 1; ++i) queue.pop();
        auto reference = std::move(queue.front());
        queue.pop();
        return reference;
    };

    auto clean() {
        std::lock_guard<std::mutex> lock{mutex};
        for (int i = 0; i < queue.size(); ++i) queue.pop();
    }
};